const validata = require("validate.js");
const { getOneBlogTypes, addBlogNumbers, updateOneBlogTypes } = require("../Dao/blogTypeDao");
const { addBlog, getPageBlog, deleteBlog, updateBlog, getOneBlog } = require("../Dao/blogDao");
const { ValidationError } = require("../utils/errors");
const { FormatJson, handleToc } = require("../utils/tool");
const { deleteMessage, getBlogIdMessage } = require("../Dao/messageDao");
// 扩展
validata.validators.iscategoryIdExits = async function (value) {
    const result = await getOneBlogTypes(value);
    if (result) {
        return;
    }
    return "categoryId is not Exist"
}

// 添加文章
module.exports.addBlogServices = async function (blogInfos) {
    // 处理toc格式的内容 以及htmlContent的内容转换
    blogInfos = handleToc(blogInfos);
    // blogInfos.toc转换为 json格式的内容
    blogInfos.toc = JSON.stringify(blogInfos.toc)
    // 规则
    const blogRules = {
        title: {
            presence: {
                allowEmpty: false
            },
            type: "string"
        },
        description: {
            presence: {
                allowEmpty: false
            },
            type: "string"
        },
        htmlContent: {
            presence: {
                allowEmpty: false
            },
            type: "string"
        },
        createDate: {
            presence: {
                allowEmpty: false
            },
            numericality: { strict: false }
        },
        thumb: {
            presence: {
                allowEmpty: false
            },
            type: "string"
        },
        categoryId: {
            presence: {
                allowEmpty: false
            },
            numericality: { strict: false },
            iscategoryIdExits: true
        },
        markdownContent: {
            presence: {
                allowEmpty: true
            },
            type: "string"
        }
    };
    // 接下来对传递过来的数据进行一个验证
    try {
        // 因为扩展的验证规则里面涉及到异步的操作，所以这里要采用异步的验证方式
        await validata.async(blogInfos, blogRules);
        delete blogInfos.markdownContent; //删除markDownContent格式的内容
        const data = await addBlog(blogInfos);
        // 添加了文章，对应的文章分类的文章，也应该添加
        await addBlogNumbers(blogInfos.categoryId);
        const categoryresult = await getOneBlogTypes(data.categoryId);
        data.category = {
            id: categoryresult.id,
            name: categoryresult.name
        }
        delete data.categoryId;
        data.toc = JSON.parse(data.toc);
        return FormatJson(0, "", data)
    } catch (err) {
        // 验证未通过
        throw new ValidationError("数据验证失败");
    }
}

// 通过分页查询其文章
module.exports.getPageBlogServices = async function (query) {
    console.log(query);
    query.page = +query.page;
    query.limit = +query.limit;
    query.categoryId = +query.categoryId;
    let data = await getPageBlog(query);
    let totalData = await getPageBlog({ page: 1, limit: query.limit });
    data = {
        total: data.count,
        rows: data.rows,
        blogTotal: totalData.count
    }
    return FormatJson(0, "", data)
}

// id删除文章
module.exports.deleteBlogServices = async function (id) {
    const data = await deleteBlog(id);
    // 删除文章同时删除文章下面的评论
    const messageIds = await getBlogIdMessage(id);
    for (const items of messageIds) {
        await deleteMessage(items.id);
    }
    return data > 0 ? FormatJson(0, "", true) : FormatJson(0, "", false);
}

// 修改文章
module.exports.updateBlogServices = async function (id, newBlogInfo) {
    // 先判断正文内容是否修改,若没有该表则不用进去,若该表则需要修改toc会进行影响
    if (newBlogInfo.htmlContent) {
        console.log("进入了");
        newBlogInfo = handleToc(newBlogInfo);
        newBlogInfo.toc = JSON.stringify(newBlogInfo.toc);
    }
    console.log(newBlogInfo, 'newBlogInfo');

    // 这里涉及到一个问题，就是文章分类有没有修改，如果有修改，之前的文章分类对应的文章数量要自减
    // 新的文章分类对应的文章数量要自增
    const oldBlogInfo = await getOneBlog(id);
    if (oldBlogInfo.categoryId && (newBlogInfo.categoryId !== oldBlogInfo.categoryId) && newBlogInfo.categoryId) {
        // 旧的文章分类进行内容
        const oldBlogType = await getOneBlogTypes(oldBlogInfo.categoryId);
        oldBlogType.articleCount--;
        await updateOneBlogTypes(oldBlogType.id, oldBlogType)

        // 新的文章分类修改
        const newBlogType = await getOneBlogTypes(newBlogInfo.categoryId);
        newBlogType.articleCount++;
        await updateOneBlogTypes(newBlogType.id, newBlogType);
    }

    const data = await updateBlog(id, newBlogInfo);
    data.rows[0].category = {
        id: data.rows[0].category.id,
        name: data.rows[0].category.name
    }
    delete data.rows[0].categoryId;
    delete data.rows[0].deletedAt;
    return FormatJson(0, "", data.rows[0]);
}

// 获取单篇文章
module.exports.getBlogOneServices = async function (id) {
    const result = await getOneBlog(id);
    const category = await getOneBlogTypes(result.categoryId);
    result.category = {
        id: category.id,
        name: category.name
    }
    delete result.categoryId;
    delete result.deletedAt;
    return FormatJson(0, "", result);
}